package org.ade.monak.anak.service;

import java.util.Calendar;
import java.util.List;
import org.ade.monak.anak.Variable.TipePesanMonak;
import org.ade.monak.anak.entity.Anak;
import org.ade.monak.anak.entity.DataMonitoring;
import org.ade.monak.anak.entity.DateMonitoring;
import org.ade.monak.anak.entity.DayMonitoring;
import org.ade.monak.anak.entity.Lokasi;
import org.ade.monak.anak.entity.Ortu;
import org.ade.monak.anak.entity.Peringatan;
import org.ade.monak.anak.map.service.LocationDistanceUtil;
import org.ade.monak.anak.map.service.LocationMonitorUtil;
import org.ade.monak.anak.service.gate.monak.SenderLokasi;
import org.ade.monak.anak.service.gate.monak.SenderPesanData;
import org.ade.monak.anak.service.storage.DatabaseManagerAnak;
import org.ade.monak.anak.service.storage.LogMonakFileManager;
import org.ade.monak.anak.service.storage.PreferenceMonitoringManager;
import org.ade.monak.anak.util.EntityBundleMaker;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

public class MainMonitoring extends Handler implements Runnable{

	public MainMonitoring(Context context, DatabaseThreadService databaseThread){
		this.context 		= context;
		this.databaseThread	= databaseThread;
		pref 				= new PreferenceMonitoringManager(context);
		locationMonitorUtil = new LocationMonitorUtil();
		databaseManager		= new DatabaseManagerAnak(context);
		handler 			= new Handler();
	}
	
	
	
	public void startMonitoring(){
		start = true;
		new Thread(this).start();
	}
	
	public boolean isStart(){
		return start;
	}
	
	public void stopMonitoring(){
		start = false;
	}
	
	
	@Override
	public void handleMessage(Message msg) {
		super.handleMessage(msg);
		final Bundle bundle = msg.getData();
		databaseThread.addDatabaseThread(new Runnable() {
			public void run() {
				List<Ortu> ortus	= databaseManager.getAllOrtu(true);
				Lokasi 	lokasiHp 	= EntityBundleMaker.getLokasiFromBundle(bundle);
				
				if(lokasiHp!=null){
					LogMonakFileManager.debug("dapet lokasi hp");
					kontrolLogLocation(lokasiHp);
					
					pref.setLastLokasi(lokasiHp);
					
					if(ortus!=null){
						
						for(Ortu ortu:ortus){
							
							if(ortu.isTrack()){
								kontrolTracking(lokasiHp, ortu);			
							}
											
						}			
					}
				}else{
					LogMonakFileManager.debug("gak dapet lokasi hp");
				}
			}
		});
		
		
	}
	
	private void cekToleransi(final Ortu ortu, final DataMonitoring dataMonitoring, final Lokasi lokasiHp){
		LogMonakFileManager.debug("hari, jam, menit yang masuk");
		Lokasi 	lokasiMonitoring 	= dataMonitoring.getLokasi();
		
		int		tolerancy			= dataMonitoring.getTolerancy();
		locationMonitorUtil.setCurrentLocation(lokasiHp);
		locationMonitorUtil.setMonitorLocation(lokasiMonitoring);
		if(tolerancy!=0){
			locationMonitorUtil.setTolerancy(dataMonitoring.getTolerancy());
		}
		if(locationMonitorUtil.isInTolerancy()){
			if(dataMonitoring.isTerlarang()){
				LogMonakFileManager.debug("terlarang masuk");
				handler.post(new Runnable(){
					public void run() {
						sendPeringatanTerlarang(ortu,dataMonitoring, lokasiHp);
					}
				});
			}						
		}else{
			LogMonakFileManager.debug("seharusnya masuk");
			if(dataMonitoring.isSeharusnya()){
				handler.post(new Runnable(){
					public void run() {
						sendPeringatanSeharusnya(ortu, dataMonitoring, lokasiHp);
					}
				});
			}
		}
	}
	
	private void sendPeringatanSeharusnya(Ortu ortu, DataMonitoring dataMonitoring, Lokasi lokasiHp){
		SenderPesanData senderMonitoring	= new SenderPesanData(context, null, ortu);
		
		Peringatan peringatan = new Peringatan();
		peringatan.setIdMonitoring(dataMonitoring.getIdMonitoring());
		peringatan.setLokasiAnak(lokasiHp);
		peringatan.setTipe(TipePesanMonak.PERINGATAN_SEHARUSNYA);
		peringatan.setIdOrtu(ortu.getIdOrtu());
		senderMonitoring.sendPeringatanSeharusnya(peringatan, dataMonitoring);
		
	}
	
	private void sendPeringatanTerlarang(Ortu ortu, DataMonitoring dataMonitoring, Lokasi lokasiHp){
		SenderPesanData senderMonitoring	= new SenderPesanData(context, null, ortu);
		
		Peringatan peringatan = new Peringatan();
		peringatan.setIdMonitoring(dataMonitoring.getIdMonitoring());
		peringatan.setLokasiAnak(lokasiHp);
		peringatan.setTipe(TipePesanMonak.PERINGATAN_TERLARANG);
		peringatan.setIdOrtu(ortu.getIdOrtu());
		senderMonitoring.sendPeringatanTerlarang(peringatan, dataMonitoring);
	}
	
	private void kontrolTracking(Lokasi lokasiHp, Ortu ortu){
		Lokasi lastLokasi = databaseManager.getLastLogLokasi();
		if(lastLokasi==null || lastLokasi.getlatitude()!=lokasiHp.getlatitude()||lastLokasi.getLongitude()!=lokasiHp.getLongitude()){
			Anak anak = new Anak();
			anak.setIdAnak(ortu.getIdAnak());
			anak.setLastLokasi(lokasiHp);

			SenderLokasi senderLokasi= new SenderLokasi(context, ortu);
			senderLokasi.sendLocationModeTracking(anak);
		}
	}
	
	private void kontrolLogLocation(Lokasi lokasi){
		LogMonakFileManager.debug("kontrol log lokasi");
		List<Lokasi> lokasis = databaseManager.getAllLogLokasi();
		Calendar cal = Calendar.getInstance();
		long maxDay = cal.getTimeInMillis()-MAX_DAY;
		cal.setTimeInMillis(maxDay);
		if(lokasis!=null){
			for(Lokasi lokasiFor:lokasis){
				if(lokasiFor.getTime()<maxDay){
					databaseManager.deleteLokasi(lokasiFor);
				}
			}
			Lokasi lokasiLama = lokasis.get(lokasis.size()-1);
			if(lokasiLama==null||LocationDistanceUtil.distanceInMeters(lokasi.getlatitude(), lokasi.getLongitude(), lokasiLama.getlatitude(), lokasiLama.getLongitude())>100){
				lokasi.setLog(true);
				databaseManager.addLokasi(lokasi);
			}		
		}else{
			lokasi.setLog(true);
			databaseManager.addLokasi(lokasi);
		}
	
	}
	public void run() {
		while(start){
			
			final Lokasi 	lokasiHp 	= pref.getLastLokasi();

			if(lokasiHp.getlatitude()==0){
				continue;
			}
			
			databaseThread.addDatabaseThread(new Runnable() {
				
				public void run() {
					List<Ortu> ortus	= databaseManager.getAllOrtu(true);
				
					LogMonakFileManager.debug("cek monitoring");
					
					if(lokasiHp!=null && ortus!=null){
						
						for(Ortu ortu:ortus){
											
							List<DataMonitoring> dataMonitorings = ortu.getDataMonitorings();
							
							if(dataMonitorings != null && locationMonitorUtil != null){
								for(DataMonitoring dataMonitoring:dataMonitorings){
									
									if(dataMonitoring.isAktif()){
										Calendar cal 	= Calendar.getInstance();
										
										int	hari 		= cal.get(Calendar.DAY_OF_WEEK);
										
										int hourNow 	= cal.get(Calendar.HOUR_OF_DAY);
										int minuteNow 	= cal.get(Calendar.MINUTE);
										
										cal.set(Calendar.HOUR_OF_DAY, 0);
										cal.set(Calendar.MINUTE, 0);
										cal.set(Calendar.SECOND, 0);
										cal.set(Calendar.MILLISECOND, 0);
										long tanggal 	= cal.getTimeInMillis();
										
										cal.setTimeInMillis(dataMonitoring.getWaktuMulai());
										int hourMulai 	= cal.get(Calendar.HOUR_OF_DAY);
										int minuteMulai = cal.get(Calendar.MINUTE);
										
										cal.setTimeInMillis(dataMonitoring.getWaktuSelesai());
										int hourSelesai 	= cal.get(Calendar.HOUR_OF_DAY);
										int minuteSelesai 	= cal.get(Calendar.MINUTE);
																				
										boolean then = false;
										
										List<DateMonitoring> tanggalMonitorings = dataMonitoring.getTanggals();
										List<DayMonitoring> hariMonitorings 	= dataMonitoring.getHaris();
										if(tanggalMonitorings!=null){
											for(DateMonitoring tanggalMonitoring:tanggalMonitorings){
													
												cal.setTimeInMillis(tanggalMonitoring.getDate());
												cal.set(Calendar.HOUR_OF_DAY, 0);
												cal.set(Calendar.MINUTE, 0);
												cal.set(Calendar.SECOND, 0);
												cal.set(Calendar.MILLISECOND, 0);
												long tanggalMonitoringMilis 	= cal.getTimeInMillis();
												
												if(tanggal == tanggalMonitoringMilis){
													LogMonakFileManager.debug("sama tanggal");
													then=true;
													break;
												}
											}
										}
										if(hariMonitorings!=null && !then){
											for(DayMonitoring hariMonitoring:hariMonitorings){
												if(hari == hariMonitoring.getHari()){
													then = true;

													break;
												}
											}
											
										}
										
										if(then){
											if((hourNow>hourMulai && hourNow<hourSelesai)){
												
												LogMonakFileManager.debug("sama jamnya");
												cekToleransi(ortu, dataMonitoring, lokasiHp);
												
											}else if(hourNow==hourMulai){
												if(minuteNow>=minuteMulai){
													cekToleransi(ortu, dataMonitoring, lokasiHp);
												}
											}else if(hourNow==hourSelesai){
												if( minuteNow<=minuteSelesai){
													cekToleransi(ortu, dataMonitoring, lokasiHp);
												}
											}
										}
									}
									
								}
							}
							
							
							
						}
						
					}
				}
			});
			
			
			try {
				Thread.sleep(10000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	private final DatabaseThreadService databaseThread;
	private final Context context;
	
	private final PreferenceMonitoringManager pref;
	
	private boolean start;
	
	private final Handler handler;
	
	private DatabaseManagerAnak		databaseManager		= null;
	private LocationMonitorUtil 	locationMonitorUtil = null;
	
	private final static long MAX_DAY = (long) 86399999.99980646;

	
}
